#include "rrcomponent.h"

RRComponent::RRComponent()
{
    map_index = 0;
}

void RRComponent::rrSetPrim(RRPrim *arg)
{
    switch(arg->rrGetType()) {
    case RR_CUBOID:
        primset[map_index] = new RRCuboid;
        break;
    case RR_PLANE:
        primset[map_index] = new RRPlane;
        break;
    case RR_QUADRIC:
        primset[map_index] = new RRQuadric;
        break;
    }
    primset[map_index]->rrSetPrim(arg);
    map_index += 1;
}

void RRComponent::rrSetMaterial(RRMaterial *arg)
{
    material.rrSetMaterial(arg);
}

void RRComponent::rrTrace(RRRay *ray, RRCrossInfo *arg)
{
    RRPrim *pr;
    RRCrossInfo cr, cr_temp;
    RRRange rng, rng_temp;
    rng.s = 0.0; rng.t = 1.0e+18;
    map<int, RRPrim*>::iterator it = primset.begin();
    while(it != primset.end()) {
        pr = (*it).second;
        pr->rrTrace(ray, &cr_temp);
        if(cr_temp.rrGetHit() == true) {
            rng_temp = cr_temp.rrGetRange();
            if(rng.s <= rng_temp.s && rng_temp.t <= rng.t) {
                rng.s = rng_temp.s;
                rng.t = rng_temp.t;
                cr.rrSetCrossInfo(&cr_temp);
                cr.rrSetRange(rng);
            }
            else if(rng.s <= rng_temp.s && rng.t <= rng_temp.t && rng_temp.s <= rng.t) {
                rng.s = rng_temp.s;
                cr = cr_temp;
                cr.rrSetRange(rng);
            }
            else if(rng_temp.s <= rng.s && rng_temp.t <= rng.t && rng.s <= rng_temp.t) {
                rng.t = rng_temp.t;
                cr.rrSetRange(rng);
            }
            else if(rng_temp.s <= rng.s && rng.t <= rng_temp.t) {

            }
            else {
                arg->rrSetHit(false);
                return;
            }
        }
        else {
            //puts("show up?");
            arg->rrSetHit(false);
            return;
        }
        it++;
    }
    //puts("so here comes");
    cr.rrSetHit(true);
    cr.rrSetMaterial(material);
    arg->rrSetCrossInfo(&cr);
    return;
}
